package com.fingard.dsp.task.command;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.nio.charset.Charset;
import java.text.ParseException;

import com.fingard.constant.Format;
import com.fingard.dsp.task.DelayCounter;
import com.fingard.dsp.task.ITask;
import com.fingard.dsp.task.TaskBase;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;

import com.fingard.FGBiz;

public class CleanUpLogFiles extends TaskBase implements ITask {

	private static DelayCounter delayCounter = new DelayCounter(480, 2);
	
	private int deleteDaysCount;//多少天之前要删除的
	private int zipDaysCount;//多少天之前要压缩备份的
	private Date today;
	/**执行*/
	@Override
	public void execTask(HashMap<String, String> pParams) {
		
		if(delayCounter.isDelay()){
			return;
		}
		
		//FGBiz.dspCenter.dspSet.logsMainDir;
		//FGBiz.dspCenter.dspSet.bankLogsDirPath;
		if(pParams.containsKey("deletedayscount") && pParams.get("deletedayscount").trim().length()> 0){
			deleteDaysCount = Integer.parseInt(pParams.get("deletedayscount"));
		}else{
			deleteDaysCount = 30;
		}
		if(pParams.containsKey("zipdayscount") && pParams.get("zipdayscount").trim().length()> 0){
			zipDaysCount = Integer.parseInt(pParams.get("zipdayscount"));
		}else{
			zipDaysCount = 3;
		}
		today = new Date();
		
		
		
		int deletedFileCount = 0;
		
		File logsDir = new File(FGBiz.dspCenter.dspSet.logsMainDir);
		deletedFileCount += cleanUpByDir(logsDir);
		
		File banklogsDir = new File(FGBiz.dspCenter.dspSet.bankLogsDirPath+File.separator+FGBiz.dspCenter.dspSet.bankLogsFirstDir);
		deletedFileCount += cleanUpByDir(banklogsDir);
		
		if(hashZipStream!=null){
			Iterator<String> iter2 = hashZipStream.keySet().iterator();
	        while (iter2.hasNext()) {
	            String eachKey2 = iter2.next();
	            try {
					hashZipStream.get(eachKey2).close();
				} catch (IOException e) {
					FGBiz.logTrace.exception("CleanUpLogFiles", e);
				}
	            try {
					hashFileStream.get(eachKey2).close();
				} catch (IOException e) {
					FGBiz.logTrace.exception("CleanUpLogFiles", e);
				}
	        }
		}
		
		String zipFileDir = StringHelper.getFileParentDir(FGBiz.dspCenter.dspSet.logsMainDir)+File.separator+"bakzip";
		File bakzip = new File(zipFileDir);
		if(bakzip.exists()){
			File[] zipFiles = bakzip.listFiles();
			if(zipFiles!=null && zipFiles.length>0){
				for(int i=0;i<zipFiles.length;i++){
					String fname = zipFiles[i].getName();
					if(fname.endsWith(".zip")){
						String[] nameSp = fname.split("_");
						if(nameSp[0].length() == 8){
							try {
								Date fdate = Format.Date8Format.parse(nameSp[0]);
								double diffDays = DateHelper.getDifferDays(today, fdate);
								if(diffDays>deleteDaysCount){
									FGBiz.logTrace.info("CleanUpLogFiles", logID + "删除"+fname);
									zipFiles[i].delete();
								}
							} catch (ParseException e) {
								FGBiz.logTrace.exception("CleanUpLogFiles", e);
							}
						}
					}
				}
			}
		}
		if(deletedFileCount>0){
			delayCounter.resetZeroCount();
		}else{
			delayCounter.increaseZeroCount();
			FGBiz.logTrace.info("CleanUpLogFiles", logID + "\t清理文件个数为0，增加轮询延时"+delayCounter.getDelayMinutes()+"分钟");
		}
	}
	private ArrayList<File> listZipDir = null;
	ArrayList<File> listZipFilePath = null;
	
	private int cleanUpByDir(File pDir){
		
		int delCount = 0;
		try {
			
			listZipDir = new ArrayList<File>();
			listZipFilePath = new ArrayList<File>();
			FGBiz.logTrace.info("CleanUpLogFiles", logID + "\t清理"+pDir.getAbsolutePath());
			cleanUpLoop(pDir, pDir.getName(), 1);
			
			if(listZipFilePath!=null && listZipFilePath.size()>0){
				for(File eachFile : listZipFilePath){
					eachFile.delete();
					delCount++;
				}
			}
			
			if(listZipDir!=null && listZipDir.size()>0){
				for(int i= listZipDir.size()-1;i>=0;i--){
					File eachFile = listZipDir.get(i);
					File[] subfiles = eachFile.listFiles();
					if(subfiles == null || subfiles.length == 0){
						eachFile.delete();
					}
				}
			}
			
		} catch (IOException e) {
			FGBiz.logTrace.exception("CleanUpLogFiles", e);
		}
		return delCount;
	}
	

	/**取轮询次数*/
	@Override
	public long getPolledCount() {
		return 0;
	}

	/**取最近一次轮询时间*/
	@Override
	public Date getLastPolledTime() {
		return null;
	}
	
	private HashMap<String, OutputStream> hashFileStream;
	private HashMap<String, ZipOutputStream> hashZipStream;
	private ZipOutputStream getZipOutputStream(Date pDate) throws IOException{
		if(hashFileStream == null){
			hashFileStream = new HashMap<String, OutputStream>();
			hashZipStream = new HashMap<String, ZipOutputStream>();
		}
		String dayStr = Format.Date8Format.format(pDate);
		if(!hashFileStream.containsKey(dayStr)){
			String zipFilePath = StringHelper.getFileParentDir(FGBiz.dspCenter.dspSet.logsMainDir)+File.separator+"bakzip";
			FileHelper.mkdirsIfNotExists(zipFilePath);
			zipFilePath+=File.separator+dayStr+"_"+Format.DateTime14Format.format(new Date())+".zip";
			File tmpFile = new File(zipFilePath);
			tmpFile.createNewFile();
			OutputStream outStream = new FileOutputStream(tmpFile);
			ZipOutputStream zipOps = new ZipOutputStream(outStream, Charset.forName("utf-8"));
			hashFileStream.put(dayStr, outStream);
			hashZipStream.put(dayStr, zipOps);
		}
		return hashZipStream.get(dayStr);
	}

	/**循环清理日志文件
	 * @param pLogDir 日志目录
	 * @throws IOException */
	private void cleanUpLoop(File pLogDir, String pName, int deep) throws IOException{
		if(deep!=1){
			listZipDir.add(pLogDir);
		}
		File[] files = pLogDir.listFiles();
		byte[] buf = new byte[4096];
		for (File eachFile : files) {
			if(eachFile.isDirectory()){
				cleanUpLoop(eachFile, pName+File.separator+eachFile.getName(),deep+1);
			}else{
				String ext = StringHelper.getFileExt(eachFile.getName());
				if("txt".equals(ext)){
					Date lastMdDate = new Date(eachFile.lastModified());
					double diffDays = DateHelper.getDifferDays(today, lastMdDate);
					if(diffDays>deleteDaysCount){
						eachFile.delete();
					}else if(diffDays>zipDaysCount){
						ZipOutputStream zipOps = getZipOutputStream(lastMdDate);
						
						zipOps.putNextEntry(new ZipEntry(pName+File.separator+eachFile.getName()));
						// copy文件到zip输出流中
						int len;
						FileInputStream in = new FileInputStream(eachFile);
						while ((len = in.read(buf)) != -1) {
							zipOps.write(buf, 0, len);
						}
						// Complete the entry
						zipOps.closeEntry();
						in.close();
						listZipFilePath.add(eachFile);
					}
				}
			}
		}
	}
}
